
/** 随机工具 */
export class RandomUtils {

    /**
     * 获取一个随机数
     * @param useSeed 是否使用随机数种子
     * @returns 
     */
    static getRandom(useSeed = true): number {
        //todo 种子接入
        return useSeed ? Math.random() : Math.random()
    }

    /**
     * 生成指定范围的随机浮点数
     * @param min   最小值
     * @param max   最大值
     * @param type  类型
     */
    static getRandomFloat(min: number = 0, max: number = 1): number {
        return this.getRandom() * (max - min) + min;
    }

    /**
     * 生成指定范围的随机整数
     * @param min   最小值
     * @param max   最大值
     * @param type  类型
     * @example
    var min = 1;
    var max = 10;
    // [min,max) 得到一个两数之间的随机整数,这个值不小于min（如果min不是整数的话，得到一个向上取整的 min），并且小于（但不等于）max  
    Randomutils.getRandomInt(min, max, 1);

    // [min,max] 得到一个两数之间的随机整数，包括两个数在内,这个值比min大（如果min不是整数，那就不小于比min大的整数），但小于（但不等于）max
    Randomutils.getRandomInt(min, max, 2);

    // (min,max) 得到一个两数之间的随机整数
    Randomutils.getRandomInt(min, max, 3);
     */
    static getRandomInt(min: number, max: number, useSeed = true, type: number = 2): number {
        min = Math.ceil(min);
        max = Math.floor(max);
        switch (type) {
            case 1: // [min,max) 得到一个两数之间的随机整数,这个值不小于min（如果min不是整数的话，得到一个向上取整的 min），并且小于（但不等于）max  
                return Math.floor(this.getRandom(useSeed) * (max - min)) + min;
            case 2: // [min,max] 得到一个两数之间的随机整数，包括两个数在内,这个值比min大（如果min不是整数，那就不小于比min大的整数），但小于（但不等于）max
                return Math.floor(this.getRandom(useSeed) * (max - min + 1)) + min;
            case 3: // (min,max) 得到一个两数之间的随机整数
                return Math.floor(this.getRandom(useSeed) * (max - min - 1)) + min + 1;
        }
        return 0;
    }

    /**
     * 根据最大值，最小值范围生成随机数数组
     * @param min   最小值
     * @param max   最大值
     * @param n     随机个数
     * @param type  类型
     * @example
    var a = Randomutils.getRandomByMinMaxList(50, 100, 5)
    console.log("随机的数字", a);
     */
    static getRandomByMinMaxList(min: number, max: number, n: number): Array<number> {
        var result: Array<number> = [];
        for (let i = 0; i < n; i++) {
            result.push(this.getRandomInt(min, max))
        }
        return result;
    }

    /**
     * 获取数组中随机对象
     * @param arr 对象数组
     * @param n 个数
     */
    static getRandomObjByArr<T>(arr: Array<T>, n: number): Array<T> {
        const temp = arr.slice()
        const res: Array<T> = []
        for (let i = 0; i < n; i++) {
            const index = this.getRandomInt(0, temp.length, true, 1);
            res.push(temp.splice(index, 1)[0])
            if (!temp.length) {
                return res
            }
        }
        return res
    }

    /**
     * 定和随机分配
     * @param n     随机数量
     * @param sum   随机元素合
     * @example
    var c = Randomutils.getRandomBySumList(5, -100);
    console.log("定和随机分配", c);
     */
    static getRandomBySumList(n: number, sum: number): number[] {
        var residue = sum;
        var value = 0;
        var result: Array<number> = [];
        for (let i = 0; i < n; i++) {
            value = this.getRandomInt(0, residue, true, 3);
            if (i == n - 1) {
                value = residue;
            }
            else {
                residue -= value;
            }
            result.push(value);
        }
        return result;
    }

    /** 获得一个随机方向向量 */
    static getRandomDirection(): { x: number, y: number } {
        // 生成一个随机角度
        const angle = this.getRandom() * Math.PI * 2;
        // 计算 x 和 y 分量
        const x = Math.cos(angle);
        const y = Math.sin(angle);
        return { x, y };
    }

}